---
title: Storybook for React Native Web
hideRendererSelector: true
sidebar:
  order: 7
  title: React Native Web
---

Storybook for React Native Web is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [React Native](https://reactnative.dev/). It uses [Vite](https://vitejs.dev/) to build your components for web browsers.

<Callout variant="info">
  In addition to React Native Web, Storybook supports on-device [React Native](https://github.com/storybookjs/react-native) development. If you're unsure what's right for you, read our [comparison](#react-native-vs-react-native-web).
</Callout>





## Install

To install Storybook in an existing React Native project, run this command in your project's root directory:

<CodeSnippets path="create-command.md" variant="new-users" copyEvent="CreateCommandCopy" />

You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/).


### Requirements

<GetStartedVersions versions={[{
  name: 'React Native',
  range: '≥ 0.72',
  icon: '/images/logos/renderers/logo-react.svg'
}, {
  name: 'React Native Web',
  range: '≥ 0.19',
  icon: '/images/logos/renderers/logo-react.svg'
}, {
  name: 'Vite',
  range: '≥ 5',
  icon: '/images/logos/builders/vite.svg'
}]} />


## Run Storybook

To run Storybook for a particular project, run the following:

<CodeSnippets path="storybook-run-dev.md" />

To build Storybook, run:

<CodeSnippets path="build-storybook-production-mode.md" />

You will find the output in the configured `outputDir` (default is `storybook-static`).



## React Native vs React Native Web

If you’re building React Native (RN) components, Storybook has two options: Native and Web.

Both options provide a catalog of your stories that hot refreshes as you edit the code in your favorite editor. However, their implementations are quite different:

- **Native** - Runs inside your React Native application. It’s high-fidelity but has a limited feature set.
- **Web** - Displays your React Native components in the browser. It’s based on Storybook for Web, which is feature-rich and mature.

{/* TODO: Don't forget about this image, otherwise remove it */}

{/* [Image: native + web] */}

### Comparison

So, which option is right for you?

**Native.** You should choose this option if you want:

- **Native features** - Your components rely on device-specific features like native modules. It runs in your actual application, in-simulator, or on-device and provides full fidelity. The web version uses `react-native-web`, which works for most components but has [limitations](https://necolas.github.io/react-native-web/docs/react-native-compatibility/).
- **Mobile publication** - You want to share your Storybook on-device as part of a test build or embedded inside your application.

**Web.** You should choose this option if you want:

- [**Sharing**](../../sharing/publish-storybook.mdx) - Publish to the web and share with your team or publicly.
- [**Documentation**](../../writing-docs/index.mdx) - Auto-generated component docs or rich markdown docs in MDX.
- [**Testing**](../../writing-tests/index.mdx) - Component, visual, and a11y tests for your components.
- [**Addons**](https://storybook.js.org/addons) - 500+ addons that improve development, documentation, testing, and integration with other tools.

**Both.** It’s also possible to use both options together. This increases Storybook’s install footprint but is a good option if you want native fidelity in addition to all of the web features. Learn more below.


### Using both React Native and React Native Web

The easiest way to use React Native and React Native Web is to select the **"Both"** option when installing Storybook. This will install and create configurations for both environments, allowing you to run Storybook for both in the same project.

When you select "Both", the installation will:
1. Install and configure React Native Storybook (on-device)
2. Install and configure React Native Web Storybook (web-based)
3. Set up both configurations in your project

After installation, you'll see instructions for both environments:
- React Native Storybook will require additional manual configuration steps (replacing app entry, wrapping metro config)
- React Native Web Storybook can be started immediately using the `storybook` command

However, you can install them separately if one version is installed. You can add a React Native Web Storybook alongside an existing React Native Storybook by running the install command and selecting "React Native Web" in the setup wizard, and vice versa.


## FAQ

### How do I migrate from the React Native Web addon?

The [React Native Web addon](https://github.com/storybookjs/addon-react-native-web) was a Webpack-based precursor to the React Native Web Vite framework (i.e., `@storybook/react-native-web-vite`). If you're using the addon, you should migrate to the framework, which is faster, more stable, maintained, and better documented. To do so, follow the steps below.

Run the following command to upgrade Storybook to the latest version:

{/* prettier-ignore-start */}

<CodeSnippets path="storybook-upgrade.md" />

{/* prettier-ignore-end */}

<Callout variant="info">
  This framework is designed to work with Storybook 8.5 and above for the best experience. We won't be able to provide support if you're using an older Storybook version.
</Callout>

Install the framework and its peer dependencies:

{/* prettier-ignore-start */}

<CodeSnippets path="react-native-web-vite-install.md" />

{/* prettier-ignore-end */}

Update your `.storybook/main.js|ts` to change the framework property and remove the `@storybook/addon-react-native-web` addon:

{/* prettier-ignore-start */}

<CodeSnippets path="react-native-web-vite-add-framework.md" />

{/* prettier-ignore-end */}

Finally, remove the addon and similar packages (i.e., `@storybook/react-webpack5` and `@storybook/addon-react-native-web`) from your project.


## API

### Options

You can pass an options object for additional configuration if needed:

```ts title=".storybook/main.ts"
import type { StorybookConfig } from '@storybook/react-native-web-vite';

const config: StorybookConfig = {
  framework: {
    name: '@storybook/react-native-web-vite',
    options: {
      modulesToTranspile: ['my-library'], // add libraries that are not transpiled for web by default

      // You should apply babel plugins and presets here for your project that you want to apply to your code
      // for example put the reanimated preset here if you are using reanimated
      // or the nativewind jsxImportSource for example
      pluginReactOptions: {
        jsxRuntime: 'automatic' | 'classic', // default: 'automatic'
        jsxImportSource: string, // default: 'react'
        babel:{
          plugins: Array<string | [string, any]>,
          presets: Array<string | [string, any]>,
          // ... other compatible babel options
        }
        include: Array<string|RegExp>, 
        exclude: Array<string|RegExp>,
        // ... other compatible @vitejs/plugin-react options
      }
    },
  },
};

export default config;
```
#### Example configuration for reanimated

```ts title=".storybook/main.ts"
const main: StorybookConfig = {
  // ... rest of config

  framework: {
    name: "@storybook/react-native-web-vite",
    options: {
      pluginReactOptions: {
        babel: {
          plugins: [
            "@babel/plugin-proposal-export-namespace-from",
            "react-native-reanimated/plugin",
          ],
        },
      },
    },
  },

  // ... rest of config
}
```

#### Example configuration for nativewind

```ts title=".storybook/main.ts"

const main: StorybookConfig = {
  // ... rest of config

  framework: {
    name: "@storybook/react-native-web-vite",
    options: {
      pluginReactOptions: {
        jsxImportSource: "nativewind",
      },
    },
  },
}
```

#### Example configuration to transpile additional node_modules

Let's say you need to transpile a library called `my-library` that is not transpiled for web by default.
You can add it to the `modulesToTranspile` option.

```ts title=".storybook/main.ts"
const main: StorybookConfig = {
  // ... rest of config

  framework: {
    name: "@storybook/react-native-web-vite",
    options: {
      modulesToTranspile: ['my-library'],
    },
  },
}
```

#### `builder`

Type: `Record<string, any>`

Configure options for the [framework's builder](../../api/main-config/main-config-framework.mdx#optionsbuilder). For this framework, available options can be found in the [Vite builder docs](../../builders/vite.mdx).
